﻿//Copyright (C) 2009  Jaco (ScionBot.com)

//This program is free software: you can redistribute it and/or modify
//it under the terms of the GNU General Public License as published by
//the Free Software Foundation, either version 3 of the License, or
//(at your option) any later version.

//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//GNU General Public License for more details.

//You should have received a copy of the GNU General Public License
//along with this program.  If not, see <http://www.gnu.org/licenses/>.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Scion.Library;
using Scion.Library.Underlying;
using System.Drawing;
using Scion.Library.Antiban;

namespace Scion.Library.RS.UI
{
    /// <summary>
    /// Contains inventory functions.
    /// </summary>
    public class Inventory : Determine
    {
        Superior super;

        /// <summary>
        /// Contains inventory functions.
        /// <param name="s">The instance of the bot.</param>
        /// </summary>
        public Inventory(Superior s)
        {
            super = s;
        }

        /// <summary>
        /// Calculates the bounds the item is in.
        /// </summary>
        /// <param name="item">The item to calculate the bounds for.</param>
        /// <returns>Returns the bounds of the item.</returns>
        public Rectangle ItemBox(int item)
        {
            if (item < 1 || item > 28)
                return new Rectangle(-1, -1, -1, -1);
            int row = item % 4;
            if (row == 0) row = 4;
            int column = item / 4;
            if ((item % 4) != 0) column++;
            return new Rectangle(518 + (row * 42), 172 + (column * 36), 560 + (row * 42), 210 + (column * 36));
        }

        private Rectangle ItemBoxClickBounds(int item)
        {
            if (item < 1 || item > 28)
                return new Rectangle(-1, -1, -1, -1);
            int row = item % 4;
            if (row == 0) row = 4;
            int column = item / 4;
            if ((item % 4) != 0) column++;
            Rectangle r = new Rectangle(518 + (row * 42), 172 + (column * 36), 560 + (row * 42), 210 + (column * 36));
            r.X += 10;
            r.Y += 10;
            r.Width -= 10;
            r.Height -= 10;
            return r;
        }

        /// <summary>
        /// Does an action to an item.
        /// </summary>
        /// <param name="item">To item to do the action for.</param>
        /// <param name="action">The action to perform (choose option). Leave blank to click.</param>
        /// <param name="actionColour">The colour of the action (choose option).</param>
        /// <returns>Returns true if the function succeeded.</returns>
        public bool DoAction(int item, string action, Color[] actionColour)
        {
            Rectangle box = ItemBoxClickBounds(item);
            if (box.X == -1) return false;
            SizeRandom sr = new SizeRandom(new Size(box.Width - box.X, box.Height - box.Y), new Point(box.X, box.Y));
            if (action == null || action == "")
                return super.Mouse.MoveClick(new PointRandom(sr.random.X, sr.random.Y, 0), true);
            super.Mouse.MoveClick(new PointRandom(sr.random.X, sr.random.Y, 0), false);
            super.Sleep(new SleepRandom(200, 300));
            ChooseOption co = new ChooseOption(super);
            return co.DoAction(actionColour, action);
        }

        /// <summary>
        /// Does an action on a found item.
        /// </summary>
        /// <param name="location">The position the item was found at.</param>
        /// <param name="action">The action to perform (choose option). Leave blank to click.</param>
        /// <param name="actionColour">The colour of the action (choose option).</param>
        /// <returns>Returns true if the function succeeded.</returns>
        public bool DoAction(PointRandom location, string action, Color[] actionColour)
        {
            if (action == null || action == "")
                return super.Mouse.MoveClick(location, true);
            super.Mouse.MoveClick(location, false);
            super.Sleep(new SleepRandom(200, 300));
            ChooseOption co = new ChooseOption(super);
            return co.DoAction(actionColour, action);
        }

        /// <summary>
        /// Finds an item in the inventory.
        /// </summary>
        /// <param name="itemTopText">The item's top text.</param>
        /// <returns>Returns the position the item was found at. If it fails to find the item, coordinates -1, -1 are returned.</returns>
        public PointRandom FindItem(string itemTopText)
        {
            for (int i = 1; i < 29; i++)
            {
                Rectangle box = ItemBoxClickBounds(i);
                if (box.X == -1) return new PointRandom(-1, -1, 0);
                if (ItemExists(i))
                {
                    SizeRandom sr = new SizeRandom(new Size(box.Width - box.X, box.Height - box.Y), new Point(box.X, box.Y));
                    super.Mouse.MoveMouse(new PointRandom(sr.random.X, sr.random.Y, 0));
                    super.Sleep(new SleepRandom(200, 300));
                    TopText tt = new TopText(super);
                    if (tt.FindText(TopText.Common, itemTopText, TopText.Tolerance))
                        return new PointRandom(sr.random.X, sr.random.Y, 0);
                }
            }
            return new PointRandom(-1, -1, 0);
        }

        /// <summary>
        /// Finds all the duplicates of the item in the inventory.
        /// </summary>
        /// <param name="itemTopText">The item's top text.</param>
        /// <returns>Returns an array of all the items found.</returns>
        public List<PointRandom> FindItems(string itemTopText)
        {
            List<PointRandom> pr = new List<PointRandom>();
            for (int i = 1; i < 29; i++)
            {
                Rectangle box = ItemBoxClickBounds(i);
                if (box.X == -1) return null;
                if (ItemExists(i))
                {
                    SizeRandom sr = new SizeRandom(new Size(box.Width - box.X, box.Height - box.Y), new Point(box.X, box.Y));
                    super.Mouse.MoveMouse(new PointRandom(sr.random.X, sr.random.Y, 0));
                    super.Sleep(new SleepRandom(200, 300));
                    TopText tt = new TopText(super);
                    if (tt.FindText(TopText.Common, itemTopText, TopText.Tolerance))
                        pr.Add(new PointRandom(sr.random.X, sr.random.Y, 0));
                }
            }
            if (pr.Count == 0) return null;
            return pr;
        }

        /// <summary>
        /// Checks to see if the item exists in item box.
        /// </summary>
        /// <param name="i">The item index.</param>
        /// <returns>Returns true if an item was found.</returns>
        public bool ItemExists(int i)
        {
            Rectangle rect = ItemBox(i);
            return Decide(super.FindColour(new Rectangle(rect.X + 5, rect.Y + 5, rect.Width - 5, rect.Height - 5), Color.FromArgb(0, 0, 1), 2));
        }

        /// <summary>
        /// Counts all the specified items in the inventory.
        /// </summary>
        /// <param name="itemTopText">The item's top text.</param>
        /// <returns>Returns the number of items found.</returns>
        public int CountItems(string itemTopText)
        {
            List<PointRandom> items = FindItems(itemTopText);
            return items.Count;
        }

        /// <summary>
        /// Checks to see how many items are in the inventory.
        /// </summary>
        /// <returns>Returns the number of items found.</returns>
        public int Count()
        {
            int count = 0;
            for (int i = 1; i < 29; i++)
            {
                if (ItemExists(i))
                    count++;
            }
            return count;
        }

        /// <summary>
        /// Checks to see if the inventory is full.
        /// </summary>
        /// <returns>Returns true if it is full.</returns>
        public bool IsFull()
        {
            return Count() == 28;
        }

        /// <summary>
        /// Checks to see if the inventory is empty.
        /// </summary>
        /// <returns>Returns true if it is empty.</returns>
        public bool IsEmpty()
        {
            return !Decide(super.FindColour(Areas.InventoryBounds, Color.FromArgb(0, 0, 1), 2));
        }

        /// <summary>
        /// Drops all of the specified items in the inventory.
        /// </summary>
        /// <param name="itemTopText">The item's top text.</param>
        /// <returns>Returns true if the function was successful.</returns>
        public bool DropAll(string itemTopText)
        {
            List<PointRandom> items = FindItems(itemTopText);
            foreach (PointRandom pr in items)
            {
                DoAction(pr, "Drop", ChooseOption.Common);
                super.Sleep(new SleepRandom(300, 400));
            }
            return true;
        }
    }
}
